---
redirect_from:
  - /http-api/graphql
---

# GraphQL API

GraphQL API enables Cube to deliver data over the HTTP protocol to
[GraphQL][graphql]-enabled data applications, e.g., most commonly, front-end
applications.

Often, the GraphQL API is used to enable the [embedded analytics][cube-ea] use
case.

Under the hood, the GraphQL API is exposed via the `/graphql` endpoint of the
[REST API][ref-rest-api].

See [GraphQL API reference][ref-ref-graphql-api] for the list of supported
requests and parameters.

<WarningBox>

Compared to the [REST API][ref-rest-api], GraphQL API currently has the
following limitations:

- No support for the [WebSockets transport][ref-websockets].
- No support for [subscriptions to changes][ref-subscriptions].
- No support for referencing [segments][ref-segments] in queries.
- No support for [compare date range queries][ref-compare-date-range].
- No support for querying [data model metadata][ref-metadata].
- No ability to apply a [pivot config][ref-pivot-config] on the front-end.

</WarningBox>

## Configuration

GraphQL API is enabled by default and secured using [API scopes][ref-api-scopes]
and [CORS][ref-cors]. To disallow access to GraphQL API, disable the `graphql`
scope, e.g., by setting the `CUBEJS_DEFAULT_API_SCOPES` environment variable to
`meta,data`.

## Getting started

First, ensure you're running Cube v0.28.58 or later. Then start the project
locally in development mode, and navigate to `http://localhost:4000/` in your
browser. After generating data models and running query you should see the
GraphiQL interface if you click 'GraphiQL' button. If you click the 'Docs'
button in the top-right, you can explore the introspected schema.

As an example, let's use the `orders` cube from the example eCommerce database:

<CodeTabs>

```yaml
cubes:
  - name: orders
    sql_table: orders

    measures:
      - name: count
        type: count

    dimensions:
      - name: status
        sql: status
        type: string

      - name: created_at
        sql: created_at
        type: time
```

```javascript
cube(`orders`, {
  sql_table: `orders`,

  measures: {
    count: {
      type: `count`,
    },
  },

  dimensions: {
    status: {
      sql: `status`,
      type: `string`,
    },

    created_at: {
      sql: `created_at`,
      type: `time`,
    },
  },
});
```

</CodeTabs>

A GraphQL query to return the number of orders by status would look something
like this:

```graphql
{
  cube {
    orders {
      count
      status
      created_at {
        day
      }
    }
  }
}
```

The equivalent query to the REST API endpoint would look like this:

```json
{
  "measures": ["orders.count"],
  "dimensions": ["orders.status"],
  "timeDimensions": [
    {
      "dimension": "orders.created_at",
      "granularity": "day"
    }
  ]
}
```

### Modifying time dimension granularity

The granularity for a time dimension can easily be changed by specifying it in
the query:

```graphql
{
  cube {
    orders {
      created_at {
        month
      }
    }
  }
}
```

[Any supported granularity][ref-schema-ref-preagg-granularity] can be used. If
you prefer to not specify a granularity, then use `value`:

```graphql
{
  cube {
    orders {
      created_at {
        value
      }
    }
  }
}
```

### Specifying filters and ranges

Filters can be set on the load query or on a specific cube. Specifying the
filter on the load query applies it to all cubes in the query. Filters can be
added to the query as follows:

```graphql
query {
  cube(limit: 100, offset: 50, timezone: "America/Los_Angeles") {
    orders(
      orderBy: { created_at: asc, count: desc }
      where: { status: { equals: "completed" } }
    ) {
      count
      status
      created_at
    }
  }
}
```

Some other differences between the JSON query filters and the GraphQL filters to
note:

- `number` values are used for number types instead of strings
- The `notSet` filter is replaced by `{ set: false }`
- New `in` and `notIn` filters to check for multiple values
- `AND` and `OR` fields for boolean operators

The GraphQL API supports `@skip` and `@include` directives too:

```graphql
query GetOrders($byStatus: Boolean) {
  cube(limit: 100, offset: 50, timezone: "America/Los_Angeles") {
    orders(
      orderBy: { created_at: asc, count: desc }
      where: { status: { equals: "completed" } }
    ) {
      count
      status @include(if: $byStatus)
      created_at
    }
  }
}
```

### Querying multiple cubes

Using the same `orders` cube as before, let's try and get the numbers of
products for each order status too. We can do this by adding the `products` cube
to our query as follows:

```graphql
{
  cube {
    orders {
      status
      count
      created_at {
        month
      }
    }
    products {
      count
    }
  }
}
```

[ref-schema-ref-preagg-granularity]:
  /reference/data-model/pre-aggregations#granularity
[ref-rest-api]: /product/apis-integrations/rest-api
[ref-api-scopes]: /product/apis-integrations/rest-api#configuration-api-scopes
[ref-cors]: /product/apis-integrations/rest-api#configuration-cors
[graphql]: https://graphql.org
[cube-ea]: https://cube.dev/use-cases/embedded-analytics
[ref-ref-graphql-api]: /reference/graphql-api
[ref-websockets]: /product/apis-integrations/rest-api/real-time-data-fetch#web-sockets
[ref-subscriptions]: /product/apis-integrations/rest-api/real-time-data-fetch#client-subscriptions
[ref-compare-date-range]: /product/apis-integrations/queries#compare-date-range-query
[ref-metadata]: /reference/rest-api#v1meta
[ref-pivot-config]: /reference/frontend/cubejs-client-core#pivotconfig
[ref-segments]: /reference/data-model/segments